/*
 * Project:     My Project Work, Copyright (C) 2011
 * Created at:  07.08.2011
 */
package de.myprojectwork.presenter;

import de.myprojectwork.common.util.CommonUtil;
import de.myprojectwork.common.util.Logger;
import de.myprojectwork.common.util.MyProjectWorkException;
import de.myprojectwork.common.util.TodoOrderNumberSorter;
import de.myprojectwork.model.DataManipulationModel;
import de.myprojectwork.model.Table;
import de.myprojectwork.model.dto.Todo;
import de.myprojectwork.view.TodoView;
import de.myprojectwork.view.View;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 *
 * @author Chris Holdschuh
 */
public class TodoPresenterImpl extends AbstractPresenter<TodoView> implements TodoPresenter {

    private DataManipulationModel model;
    
    List<Todo> todoList;
    Todo todoForEdit;
    
    public TodoPresenterImpl(DataManipulationModel model) { 
        this.model = model;
    }
    
    public void setView(TodoView view) {
        this.view = view;
    }

    @Override
    protected void update() {
        try {
            loadTodoList();
            Collections.sort(todoList, new TodoOrderNumberSorter());
            view.setTodoList(todoList);
            
            for (Todo t : todoList) {
                Logger.info(t.getOrderNumber() + " - " + t.getText());
            }
            
        } catch (MyProjectWorkException ex) {
            // TODO: Meldungen
            ex.printStackTrace();
        }
    }
    
    @Override
    public void initUi() throws MyProjectWorkException {
        view.initUi();
        loadTodoList();
        Collections.sort(todoList, new TodoOrderNumberSorter());
        view.setTodoList(todoList);
    }

    @Override
    public void newTodo(String text, Date targentDate, int statusPercent, int orderNumber, Todo parent) {
        
        try {
            if (text != null && text.length() > 0) {
                Todo todo = todoForEdit != null ? todoForEdit : new Todo();
                if (todo.getId() <= 0) {
                    todoList.add(todo);
                }
                todo.setProject(getCurrentProject());
                todo.setParent(parent);
                todo.setStatusPercent(statusPercent);
                todo.setText(text);
                todo.setTargetDate(targentDate);
                if (!todoList.isEmpty()) {
                    todo.setOrderNumber(orderNumber);
                    pushOrderNumberDown(todoList, todo);
                } else {
                    todo.setOrderNumber(1);
                }

                model.save(todoList);
            }
            todoForEdit = null;
            view.clearInput();
            updateAll();
            
        } catch (MyProjectWorkException ex) {
            // TODO: Meldungen
            ex.printStackTrace();
        }
        
    }
    
    @Override
    public void editTodo(Todo todo) {
        todoForEdit = todo;
        view.setTodo(todo);
    }

    @Override
    public void deleteTodo() {
        if (todoForEdit != null) {
            try {
                model.delete(todoForEdit);
                model.reorgTodoOrderNumbers(getCurrentProject());
                view.clearInput();
                todoForEdit = null;
                updateAll();
                
            } catch (MyProjectWorkException ex) {
                ex.printStackTrace();
            }
        } else {
            Logger.info("Nix zum Löschen, weil todoFroEdit null ist.");
        }
    }

    @Override
    public void notifySelectedTodo(Todo todo) {
        int fkParent = todo != null ? todo.getFkParent() : 0;
        List<Todo> childList = new ArrayList<>();
        for (Todo t : todoList) {
            if (t.getFkParent() == fkParent) {
                childList.add(t);
            }
        }
        
        int max = 0;
        if (todoForEdit != null && todoForEdit.getFkParent() == fkParent) {
            max = childList.size();
        } else {
            max = childList.size()+1;
        }
        
        int current = 0;
        if (todoForEdit != null && todoForEdit.getFkParent() != fkParent) {
            current = max;
        } else if (todoForEdit != null) {
            current = todoForEdit.getOrderNumber();
        } else {
            current = max;
        }
        view.setMaxValuePrio(max, current);
    }
    
    private void pushOrderNumberDown(List<Todo> list, Todo newTodo) {
        for (Todo oldTodo : list) {
            if (oldTodo.getFkParent() == newTodo.getFkParent() 
                    && oldTodo.getOrderNumber() == newTodo.getOrderNumber()
                    && oldTodo.getId() != newTodo.getId()) {
                int childCount = 0;
                for (Todo t : list) {
                    if (t.getFkParent() == oldTodo.getFkParent()) {
                        childCount++;
                    }
                }
                int nextOrderNumber = oldTodo.getOrderNumber()+1;
                if (childCount > nextOrderNumber) {
                    Logger.info("change OrderNumber: old {" + oldTodo.getText() + "} " + oldTodo.getOrderNumber() + " -> " + nextOrderNumber);
                    oldTodo.setOrderNumber(nextOrderNumber);
                    pushOrderNumberDown(list, oldTodo);
                }
            }
        }
    }
    
    private void loadTodoList() throws MyProjectWorkException {
        todoList = model.get(Table.TODO, Table.TODO.clazz(), getCurrentProject());
    }
}
